<template>
  <div class="timeline-container">
    <div class="timeline-header">
      <h2 class="timeline-title">智能历史时间线</h2>
      <p class="timeline-subtitle">基于AI智能分析，自动识别并突出展示关键事件</p>
    </div>

    <div class="timeline-wrapper" ref="timelineWrapper">
      <!-- 时间轴主体 -->
      <div
          class="timeline-content"
          ref="timelineContent"
          :style="{ transform: `translateX(${translateX}px)` }"
          @wheel="handleWheel"
      >
        <!-- 时间轴背景线 -->
        <div class="timeline-track" :style="{ width: `${timelineWidth}px` }"></div>

        <!-- 历史事件标记点 -->
        <div class="timeline-events">
          <div
              v-for="event in processedEvents"
              :key="event.id"
              class="event-marker"
              :class="{ 'active': selectedEvent?.id === event.id }"
              :style="{
                left: `${event.position}px`,
                '--marker-color': event.color
              }"
              @click="selectEvent(event,$event)"
          >
            <div class="event-dot"></div>
            <div class="event-time">{{ event.time }}</div>
          </div>
        </div>

        <!-- 当前查看位置指示器 -->
        <div class="current-position-indicator" :style="{ left: `${currentViewPosition}px` }">
          <div class="position-line"></div>
          <div class="position-handle"></div>
        </div>
      </div>
    </div>

    <!-- 事件详情面板 -->
    <transition name="slide-up">
      <div v-if="selectedEvent" class="event-detail-panel" ref="eventDetailPanel">
        <div class="detail-header">
          <div class="detail-time-info">
            <div class="detail-time">{{ selectedEvent.time }}</div>
            <div class="detail-type" :style="{
              backgroundColor: selectedEvent.color + '20',
              color: selectedEvent.color,
              borderColor: selectedEvent.color + '40'
            }">
              {{ selectedEvent.icon }} {{ selectedEvent.typeName }}
            </div>
          </div>
          <button class="close-btn" @click="selectedEvent = null">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <line x1="18" y1="6" x2="6" y2="18"></line>
              <line x1="6" y1="6" x2="18" y2="18"></line>
            </svg>
          </button>
        </div>
        <div class="detail-content">
          <h3 class="detail-title">{{ selectedEvent.title }}</h3>
          <p class="detail-description">{{ selectedEvent.description }}</p>

          <!-- 分析部分 -->
          <div class="analysis-section">
            <h4 class="analysis-title">
              <span class="analysis-icon">{{ selectedEvent.analysisIcon }}</span>
              {{ selectedEvent.analysisType }}
            </h4>
            <div class="analysis-content">
              <div class="analysis-points">
                <div v-for="point in selectedEvent.analysisPoints" :key="point" class="analysis-point">
                  <span class="point-bullet">•</span>
                  {{ point }}
                </div>
              </div>
              <div v-if="selectedEvent.suggestion" class="suggestion-box" :style="{
                backgroundColor: selectedEvent.color + '10',
                borderColor: selectedEvent.color + '30'
              }">
                <div class="suggestion-title">💡 优化建议</div>
                <div class="suggestion-text">{{ selectedEvent.suggestion }}</div>
              </div>
            </div>
          </div>

          <div v-if="selectedEvent.tags" class="detail-tags">
            <span
                v-for="tag in selectedEvent.tags"
                :key="tag"
                class="tag"
                :style="{
                backgroundColor: selectedEvent.color + '20',
                color: selectedEvent.color,
                borderColor: selectedEvent.color + '40'
              }"
            >
              {{ tag }}
            </span>
          </div>
        </div>
      </div>
    </transition>

    <!-- 时间线控制 -->
    <div class="timeline-controls">
      <div class="view-info">
        事件跨度: {{ getTimeSpan() }}
      </div>
      <!-- 事件导航按钮 -->
      <div class="event-navigation">
        <button
            @click="goToPreviousEvent($event)"
            :disabled="!canGoPrevious"
            class="nav-btn prev-btn"
            :class="{ 'disabled': !canGoPrevious }"
        >
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <polyline points="15,18 9,12 15,6"></polyline>
          </svg>
          上一个事件
        </button>
        <div class="event-counter">
          {{ currentEventIndex + 1 }} / {{ processedEvents.length }}
        </div>
        <button
            @click="goToNextEvent($event)"
            :disabled="!canGoNext"
            class="nav-btn next-btn"
            :class="{ 'disabled': !canGoNext }"
        >
          下一个事件
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <polyline points="9,18 15,12 9,6"></polyline>
          </svg>
        </button>
      </div>
      <button @click="resetView" class="control-btn">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path>
          <path d="M21 3v5h-5"></path>
          <path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path>
          <path d="M3 21v-5h5"></path>
        </svg>
        重置视图
      </button>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {ref, reactive, computed, onMounted, onUnmounted} from 'vue'
import {useRoute} from "vue-router";

// 响应式数据
const timelineWrapper = ref()
const timelineContent = ref()
const translateX = ref(0)
const selectedEvent = ref()

const eventDetailPanel = ref()

const route = useRoute();

const resumeId = Number.parseInt(route.params.id as string)

// 定义事件类型配置
const eventTypes = [
  {
    type: 'highlight',
    name: '闪光点',
    color: '#10b981',
    icon: '✨',
    analysisType: '精彩赏析',
    analysisIcon: '🎯'
  },
  {
    type: 'warning',
    name: '危险信号',
    color: '#ef4444',
    icon: '⚠️',
    analysisType: '回答优化',
    analysisIcon: '🔧'
  },
  {
    type: 'skill',
    name: '技能展示',
    color: '#3b82f6',
    icon: '🛠️',
    analysisType: '技能分析',
    analysisIcon: '📊'
  },
  {
    type: 'interaction',
    name: '沟通互动',
    color: '#8b5cf6',
    icon: '💬',
    analysisType: '互动评估',
    analysisIcon: '🤝'
  },
  {
    type: 'milestone',
    name: '关键节点',
    color: '#f59e0b',
    icon: '🎯',
    analysisType: '节点分析',
    analysisIcon: '📈'
  }
]

// 面试事件数据
const rawEvents = reactive([
  {
    id: 1,
    time: '0:02:30',
    type: 'milestone',
    title: '自我介绍开场',
    description: '候选人开始自我介绍，展示了清晰的表达能力和良好的逻辑结构。语速适中，内容涵盖了教育背景、工作经验和个人优势。',
    analysisPoints: [
      '开场自信，语调平稳',
      '逻辑结构清晰，先后顺序合理',
      '时间控制得当，没有超时'
    ],
    suggestion: '可以在开头增加一个简短的个人亮点总结，让面试官快速了解你的核心竞争力。',
    tags: ['开场', '逻辑性', '时间管理']
  },
  {
    id: 2,
    time: '0:05:45',
    type: 'highlight',
    title: '项目经验精彩阐述',
    description: '候选人详细介绍了一个复杂的技术项目，展现了出色的技术深度和项目管理能力。使用了具体的数据和成果来支撑描述。',
    analysisPoints: [
      '技术细节描述准确，展现专业能力',
      '用具体数据支撑成果（性能提升30%）',
      '体现了团队协作和领导能力'
    ],
    suggestion: '继续保持这种用数据说话的方式，可以准备更多量化指标来展示项目价值。',
    tags: ['技术深度', '数据驱动', '团队协作']
  },
  {
    id: 3,
    time: '0:08:15',
    type: 'warning',
    title: '技术问题回答不够深入',
    description: '面试官询问关于系统架构的问题时，候选人的回答较为表面，缺乏深入的技术细节和实际应用场景的分析。',
    analysisPoints: [
      '回答过于概括，缺乏具体实例',
      '没有展示对底层原理的理解',
      '错过了展示技术广度的机会'
    ],
    suggestion: '准备一些具体的技术案例，包括遇到的挑战、解决方案和学到的经验。可以画图或举例来说明复杂概念。',
    tags: ['技术深度', '案例准备', '表达能力']
  },
  {
    id: 4,
    time: '0:12:20',
    type: 'skill',
    title: '编程能力现场展示',
    description: '候选人在白板编程环节表现出色，思路清晰，代码规范，并且能够优化算法复杂度。展现了扎实的编程基础。',
    analysisPoints: [
      '算法思路清晰，先分析再编码',
      '代码风格良好，变量命名规范',
      '主动优化时间复杂度，展现技术追求'
    ],
    suggestion: '在编码过程中可以多与面试官交流思路，展示你的思考过程和沟通能力。',
    tags: ['算法能力', '编程规范', '优化思维']
  },
  {
    id: 5,
    time: '0:15:30',
    type: 'interaction',
    title: '与面试官良好互动',
    description: '候选人主动询问了公司的技术栈和团队文化，展现了对职位的真正兴趣和良好的沟通技巧。',
    analysisPoints: [
      '主动提问，展现求知欲和兴趣',
      '问题有针对性，体现了事前准备',
      '倾听能力强，能够基于回答继续深入'
    ],
    suggestion: '可以准备更多关于公司发展方向和个人成长机会的问题，展示长期合作的意愿。',
    tags: ['主动性', '沟通技巧', '职业规划']
  },
  {
    id: 6,
    time: '0:18:45',
    type: 'warning',
    title: '薪资期望表达不当',
    description: '在讨论薪资期望时，候选人显得过于直接和强硬，没有充分考虑市场情况和自身定位。',
    analysisPoints: [
      '缺乏市场调研，期望值偏高',
      '表达方式过于直接，缺乏灵活性',
      '没有展示对非薪资福利的关注'
    ],
    suggestion: '提前了解行业薪资水平，表达期望时可以给出一个合理的范围，并强调对成长机会的重视。',
    tags: ['薪资谈判', '市场认知', '沟通技巧']
  },
  {
    id: 7,
    time: '0:22:10',
    type: 'highlight',
    title: '学习能力突出展现',
    description: '候选人分享了自学新技术的经历，展现了强烈的学习动机和自我驱动能力，给面试官留下深刻印象。',
    analysisPoints: [
      '学习方法系统化，有明确的学习路径',
      '能够快速掌握新技术并应用到实际项目',
      '展现了持续学习的习惯和热情'
    ],
    suggestion: '可以分享一些学习成果的具体案例，比如开源项目贡献或技术博客文章。',
    tags: ['学习能力', '自驱力', '技术热情']
  },
  {
    id: 8,
    time: '0:25:00',
    type: 'milestone',
    title: '面试总结与收尾',
    description: '面试进入尾声，候选人做了简洁的总结，重申了对职位的兴趣，并询问了后续流程。整体表现专业。',
    analysisPoints: [
      '总结简洁有力，突出核心优势',
      '表达了强烈的加入意愿',
      '主动了解后续流程，体现专业性'
    ],
    suggestion: '可以在最后留下一个深刻的印象点，比如分享一个能体现你价值观的小故事。',
    tags: ['总结能力', '专业性', '积极态度']
  }
])

// 当前选中事件的索引 - 修改为基于当前位置的最近事件
const currentEventIndex = computed(() => {
  if (processedEvents.value.length === 0) return -1
  const currentPos = currentViewPosition.value
  // 找到当前位置左侧最近的事件
  let nearestIndex = -1
  let minDistance = Infinity
  for (let i = 0; i < processedEvents.value.length; i++) {
    const event = processedEvents.value[i]
    // 只考虑位置在当前位置左侧或相等的事件
    if (event.position <= currentPos) {
      const distance = currentPos - event.position
      if (distance < minDistance) {
        minDistance = distance
        nearestIndex = i
      }
    }
  }
  // 如果没有找到左侧的事件，返回第一个事件的索引
  if (nearestIndex === -1 && processedEvents.value.length > 0) {
    return 0
  }
  return nearestIndex
})

// 是否可以跳转到上一个事件
const canGoPrevious = computed(() => {
  return processedEvents.value.length > 0 && currentEventIndex.value > 0
})

// 是否可以跳转到下一个事件
const canGoNext = computed(() => {
  return processedEvents.value.length > 0 && currentEventIndex.value < processedEvents.value.length - 1
})

// 跳转到上一个事件
const goToPreviousEvent = (e) => {
  if (!canGoPrevious.value) return

  const prevIndex = currentEventIndex.value - 1
  const prevEvent = processedEvents.value[prevIndex]
  selectEvent(prevEvent, e)
}

// 跳转到下一个事件
const goToNextEvent = (e) => {
  if (!canGoNext.value) return

  const nextIndex = currentEventIndex.value + 1
  const nextEvent = processedEvents.value[nextIndex]
  selectEvent(nextEvent, e)
}

// 自动选择第一个事件（在组件挂载时）
const autoSelectFirstEvent = () => {
  // if (processedEvents.value.length > 0 && !selectedEvent.value) {
  //   selectedEvent.value = processedEvents.value[0]
  // }
}

// 时间字符串转换为秒数
const timeToSeconds = (timeStr) => {
  const parts = timeStr.split(':')
  const hours = parseInt(parts[0]) || 0
  const minutes = parseInt(parts[1]) || 0
  const seconds = parseInt(parts[2]) || 0
  return hours * 3600 + minutes * 60 + seconds
}

// 秒数转换为时间字符串
const secondsToTime = (seconds) => {
  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  const secs = seconds % 60
  return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
}

// 计算智能时间映射
const createSmartTimeMapping = () => {
  // 将所有事件时间转换为秒数并排序
  const eventTimes = rawEvents.map(event => timeToSeconds(event.time)).sort((a, b) => a - b)
  const minTime = Math.min(...eventTimes)
  const maxTime = Math.max(...eventTimes)

  // 创建时间段，每个事件周围分配更多空间
  const segments = []
  const baseSpacing = 200 // 基础间距
  const eventSpacing = 300 // 事件周围的额外空间

  let currentPosition = 100 // 起始位置

  for (let i = 0; i < eventTimes.length; i++) {
    const eventTime = eventTimes[i]
    const prevEventTime = i > 0 ? eventTimes[i - 1] : minTime

    // 计算时间间隔
    const timeGap = eventTime - prevEventTime

    // 根据时间间隔调整位置间距
    if (i > 0) {
      // 如果时间间隔很大，压缩空间；如果很小，扩展空间
      const normalizedGap = Math.min(timeGap / 300, 3) // 最大3倍间距
      currentPosition += baseSpacing * Math.max(0.5, normalizedGap)
    }

    segments.push({
      time: eventTime,
      position: currentPosition
    })

    currentPosition += eventSpacing
  }

  return segments
}

// 根据时间获取位置
const getPositionFromTime = (timeStr) => {
  const seconds = timeToSeconds(timeStr)
  const mapping = createSmartTimeMapping()

  // 找到最接近的时间段
  for (let i = 0; i < mapping.length; i++) {
    if (mapping[i].time === seconds) {
      return mapping[i].position
    }
  }

  // 如果没有精确匹配，进行插值
  for (let i = 0; i < mapping.length - 1; i++) {
    if (seconds >= mapping[i].time && seconds <= mapping[i + 1].time) {
      const ratio = (seconds - mapping[i].time) / (mapping[i + 1].time - mapping[i].time)
      return mapping[i].position + ratio * (mapping[i + 1].position - mapping[i].position)
    }
  }

  return mapping[0]?.position || 100
}

// 处理后的事件数据（包含计算的position）
// 为事件添加类型相关信息
const processedEvents = computed(() => {
  return rawEvents.map(event => {
    const eventType = eventTypes.find(type => type.type === event.type)
    return {
      ...event,
      position: getPositionFromTime(event.time),
      timeInSeconds: timeToSeconds(event.time),
      color: eventType.color,
      icon: eventType.icon,
      typeName: eventType.name,
      analysisType: eventType.analysisType,
      analysisIcon: eventType.analysisIcon
    }
  }).sort((a, b) => a.timeInSeconds - b.timeInSeconds)
})

// 计算时间线总宽度
const timelineWidth = computed(() => {
  const positions = processedEvents.value.map(event => event.position)
  return Math.max(...positions) + 200
})

// 当前查看位置指示器位置（指向选中的事件）
const currentViewPosition = computed(() => {
  // 显示选中事件位置
  if (selectedEvent.value) {
    return selectedEvent.value.position
  }
  // 如果没有选中事件，显示视窗中心位置
  if (!timelineWrapper.value) return 0
  return Math.abs(translateX.value) + timelineWrapper.value.clientWidth / 2
})

// 获取时间跨度
const getTimeSpan = () => {
  if (processedEvents.value.length === 0) return '无事件'
  const firstEvent = processedEvents.value[0]
  const lastEvent = processedEvents.value[processedEvents.value.length - 1]
  return `${firstEvent.time} - ${lastEvent.time}`
}

// 选择事件
const selectEvent = (event, e = null) => {
  // 如果有事件对象，阻止冒泡
  if (e) {
    e.stopPropagation()
  }
  selectedEvent.value = event
  // 将选中的事件居中显示
  if (timelineWrapper.value) {
    const targetTranslateX = -(event.position - timelineWrapper.value.clientWidth / 2)
    const maxTranslate = 100
    const minTranslate = -(timelineWidth.value - timelineWrapper.value.clientWidth + 100)
    translateX.value = Math.max(minTranslate, Math.min(maxTranslate, targetTranslateX))
  }
}
// 处理点击外部关闭详情面板

const handleClickOutside = (e) => {
  if (selectedEvent.value && eventDetailPanel.value) {
    // 检查点击是否在详情面板外部
    if (!eventDetailPanel.value.contains(e.target)) {
      selectedEvent.value = null
    }
  }
}

// 重置视图
const resetView = () => {
  translateX.value = 0
  selectedEvent.value = null
}

// 适应所有事件
const fitAllEvents = () => {
  if (!timelineWrapper.value || processedEvents.value.length === 0) return

  const firstEventPos = processedEvents.value[0].position
  const lastEventPos = processedEvents.value[processedEvents.value.length - 1].position
  const eventsWidth = lastEventPos - firstEventPos
  const wrapperWidth = timelineWrapper.value.clientWidth

  if (eventsWidth < wrapperWidth) {
    // 如果所有事件都能显示，居中显示
    translateX.value = -(firstEventPos - (wrapperWidth - eventsWidth) / 2 - 50)
  } else {
    // 如果事件太多，显示第一个事件
    translateX.value = -(firstEventPos - 100)
  }

  selectedEvent.value = null
}

// 滚轮事件处理
const handleWheel = (e) => {
  if (!timelineWrapper.value) return

  e.preventDefault()

  // 计算滚动增量
  const delta = e.deltaY > 0 ? -50 : 50 // 向下滚动时向左移动，向上滚动时向右移动
  const newTranslateX = translateX.value + delta

  // 限制滚动范围
  const maxTranslate = 100
  const minTranslate = -(timelineWidth.value - timelineWrapper.value.clientWidth + 100)

  translateX.value = Math.max(minTranslate, Math.min(maxTranslate, newTranslateX))
}

// 键盘事件处理
const handleKeydown = (e) => {
  if (e.key === 'ArrowLeft' && canGoPrevious.value) {
    e.preventDefault()
    goToPreviousEvent()
  } else if (e.key === 'ArrowRight' && canGoNext.value) {
    e.preventDefault()
    goToNextEvent()
  }
}

// 组件挂载时自动适应所有事件并选择第一个
onMounted(() => {
  setTimeout(() => {
    fitAllEvents()
    autoSelectFirstEvent()
  }, 100)

  // 添加键盘和滚轮事件监听
  document.addEventListener('keydown', handleKeydown)
  if (timelineWrapper.value) {
    timelineWrapper.value.addEventListener('wheel', handleWheel, {passive: false})
  }
  // 添加全局点击事件监听
  document.addEventListener('click', handleClickOutside)
})

// 组件卸载时清理
onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
  if (timelineWrapper.value) {
    timelineWrapper.value.removeEventListener('wheel', handleWheel)
  }
  // 清理全局点击事件监听
  document.removeEventListener('click', handleClickOutside)
})

const showReport = ref(false)
const viewReport = () => {
  showReport.value = true
}


// 监听模态框状态变化
watch(showReport, (newValue) => {
  if (newValue) {
    // 防止背景滚动
    document.body.style.overflow = 'hidden'
  } else {
    // 恢复背景滚动
    document.body.style.overflow = 'auto'
  }
})
</script>

<style scoped>
/* 组件入场动画 */
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideInUp {
  from {
    transform: translateY(30px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes slideInRight {
  from {
    transform: translateX(30px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes scaleIn {
  from {
    transform: scale(0.9);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.timeline-container {
  width: 70vw;
  min-height: 80vh;
  background: linear-gradient(135deg, #e6f2ff 0%, #cce4ff 50%, #e0f0ff 100%);
  padding: 2rem;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  border-radius: 10px;
  border: 1px solid #c7dbf2;
  animation: fadeIn 0.8s ease-out forwards;
}

.timeline-header {
  text-align: center;
  margin-bottom: 3rem;
  color: #2c5282;
  animation: slideInUp 0.8s ease-out forwards;
}

.timeline-title {
  font-size: 3rem;
  font-weight: 700;
  margin: 0 0 0.5rem 0;
  text-shadow: 0 1px 2px rgba(44, 82, 130, 0.1);
  color: #1a365d;
}

.timeline-subtitle {
  font-size: 1.2rem;
  opacity: 0.8;
  margin: 0;
  color: #2c5282;
}

.timeline-wrapper {
  width: 100%;
  height: 200px;
  overflow: hidden;
  background: rgba(235, 246, 255, 0.8);
  backdrop-filter: blur(10px);
  border-radius: 20px;
  border: 1px solid #c7dbf2;
  position: relative;
  cursor: default;
  margin-bottom: 2rem;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
  animation: scaleIn 1s ease-out 0.3s both;
}

.timeline-content {
  position: relative;
  height: 100%;
  transition: transform 0.3s ease;
  user-select: none;
}

.timeline-track {
  position: absolute;
  top: 50%;
  left: 0;
  height: 4px;
  background: linear-gradient(90deg, #63b3ed, #90cdf4, #63b3ed);
  border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transform: translateY(-50%);
}

.timeline-events {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.event-marker {
  position: absolute;
  top: 62%;
  transform: translate(-50%, -50%);
  cursor: pointer;
  transition: all 0.3s ease;
  z-index: 5;
  animation: fadeIn 0.5s ease-out forwards;
  animation-delay: calc(0.1s * var(--marker-index, 0));
}

.event-marker:hover {
  transform: translate(-50%, -50%) scale(1.1);
}

.event-marker.active {
  transform: translate(-50%, -50%) scale(1.2);
  z-index: 10;
}

.event-dot {
  width: 20px;
  height: 20px;
  background: var(--marker-color);
  border: 3px solid #ffffff;
  border-radius: 50%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  margin: 0 auto 12px;
  position: relative;
}

.event-dot::after {
  content: '';
  position: absolute;
  top: -6px;
  left: -6px;
  right: -6px;
  bottom: -6px;
  border-radius: 50%;
  background: var(--marker-color);
  opacity: 0.2;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    transform: scale(0.9);
    opacity: 0.3;
  }
  50% {
    transform: scale(1.1);
    opacity: 0.1;
  }
  100% {
    transform: scale(0.9);
    opacity: 0.3;
  }
}

.event-time {
  font-size: 0.8rem;
  font-weight: 600;
  color: #2c5282;
  text-align: center;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  padding: 0.5rem 0.75rem;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  white-space: nowrap;
  border: 1px solid #c7dbf2;
}

.current-position-indicator {
  position: absolute;
  top: 0;
  height: 100%;
  pointer-events: none;
  z-index: 3;
}

.position-line {
  width: 2px;
  height: 100%;
  background: rgba(99, 179, 237, 0.6);
  margin: 0 auto;
  box-shadow: 0 0 6px rgba(99, 179, 237, 0.3);
}

.position-handle {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 12px;
  background: #ffffff;
  border: 3px solid #4299e1;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  box-shadow: 0 2px 8px rgba(66, 153, 225, 0.3);
}

.slide-up-enter-active,
.slide-up-leave-active {
  transition: all 0.3s ease;
  transform-origin: top center;
}

.slide-up-enter-from,
.slide-up-leave-to {
  transform: translateY(20px);
  opacity: 0;
}

.event-detail-panel {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #ffffff;
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.08);
  padding: 2rem;
  max-height: 45vh;
  overflow-y: auto;
  z-index: 100;
  border-top: 1px solid #c7dbf2;
}

.detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
}

.detail-time-info {
  display: flex;
  flex-direction: row;
  gap: 1.5rem;
}

.detail-time {
  font-size: 1rem;
  color: #4a5568;
  font-weight: 600;
}

.close-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: #4a5568;
  padding: 0.5rem;
  border-radius: 8px;
  transition: all 0.2s ease;
}

.close-btn:hover {
  background: #ebf8ff;
  color: #2c5282;
}

.detail-title {
  font-size: 1.5rem;
  font-weight: 700;
  color: #1a365d;
  margin: 0 0 1rem 0;
}

.detail-description {
  font-size: 1rem;
  line-height: 1.6;
  color: #4a5568;
  margin: 0 0 1.5rem 0;
}

.analysis-section {
  background: #f8fafc;
  border-radius: 12px;
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  border: 1px solid #e2e8f0;
}

.analysis-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.1rem;
  font-weight: 700;
  color: #1f2937;
  margin: 0 0 1rem 0;
}

.analysis-icon {
  font-size: 1.2rem;
}

.analysis-content {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.analysis-points {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.analysis-point {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.9rem;
  line-height: 1.5;
  color: #2d3748;
}

.point-bullet {
  color: #4299e1;
  font-weight: bold;
  margin-top: 0.1rem;
}

.suggestion-box {
  padding: 1rem;
  border-radius: 8px;
  border: 1px solid;
  background-color: rgba(235, 248, 255, 0.5);
}

.suggestion-title {
  font-weight: 600;
  color: #1a365d;
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
}

.suggestion-text {
  font-size: 0.9rem;
  line-height: 1.5;
  color: #4a5568;
}

.detail-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tag {
  padding: 0.25rem 0.75rem;
  border-radius: 20px;
  font-size: 0.8rem;
  font-weight: 600;
  border: 1px solid currentColor;
  background-color: rgba(235, 248, 255, 0.5);
}

.view-info {
  font-size: 20px;
  color: #2c5282;
  font-weight: 600;
  text-align: center;
  flex: 1;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  max-width: 15vw;
}

.event-navigation {
  display: flex;
  align-items: center;
  gap: 1rem;
  background: rgba(235, 248, 255, 0.8);
  backdrop-filter: blur(10px);
  padding: 0.75rem 1rem;
  border-radius: 12px;
  border: 1px solid #bee3f8;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.nav-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  border: 1px solid #bee3f8;
  border-radius: 8px;
  font-size: 0.8rem;
  font-weight: 600;
  color: #2c5282;
  cursor: pointer;
  transition: all 0.3s ease;
  white-space: nowrap;
}

.nav-btn:hover:not(.disabled) {
  background: rgba(255, 255, 255, 0.95);
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  color: #1a365d;
}

.nav-btn.disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: rgba(235, 248, 255, 0.5);
  color: #90cdf4;
}

.nav-btn.disabled:hover {
  transform: none;
  box-shadow: none;
}

.event-counter {
  font-size: 0.875rem;
  font-weight: 600;
  color: #2c5282;
  text-shadow: none;
  padding: 0 0.5rem;
  background: rgba(255, 255, 255, 0.6);
  border-radius: 6px;
  border: 1px solid #bee3f8;
}

.timeline-controls {
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(235, 248, 255, 0.6);
  backdrop-filter: blur(10px);
  padding: 1.5rem;
  border-radius: 16px;
  border: 1px solid #bee3f8;
  gap: 2rem;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  animation: slideInRight 0.8s ease-out 0.6s both;
}

.control-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  border: 1px solid #bee3f8;
  border-radius: 12px;
  font-size: 0.875rem;
  font-weight: 600;
  color: #2c5282;
  cursor: pointer;
  transition: all 0.3s ease;
  white-space: nowrap;
}

.control-btn:hover {
  background: rgba(255, 255, 255, 0.95);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  color: #1a365d;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .timeline-container {
    padding: 1rem;
  }

  .timeline-title {
    font-size: 2rem;
  }

  .timeline-subtitle {
    font-size: 1rem;
  }

  .timeline-controls {
    flex-direction: column;
    gap: 1rem;
    text-align: center;
  }

  .event-navigation {
    order: -1;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.75rem;
  }

  .nav-btn {
    font-size: 0.75rem;
    padding: 0.4rem 0.8rem;
  }

  .event-counter {
    font-size: 0.8rem;
    order: -1;
    width: 100%;
    text-align: center;
    margin-bottom: 0.5rem;
  }

  .control-btn {
    width: 100%;
    justify-content: center;
  }

  .event-detail-panel {
    padding: 1.5rem;
    max-height: 60vh;
  }

  .detail-title {
    font-size: 1.25rem;
  }

  .detail-description {
    font-size: 0.9rem;
  }

  .event-time {
    font-size: 0.75rem;
    padding: 0.4rem 0.6rem;
  }

  .event-dot {
    width: 16px;
    height: 16px;
    border-width: 3px;
  }
}
</style>
